package engine.sound;

import java.util.ArrayList;
import java.util.HashMap;

public class Musicplayer {
	
	private HashMap<String, Sound> tracks = new HashMap<String, Sound>();
	private ArrayList<String> tracksID = new ArrayList<String>();
	
	private String current = "";
	private int next = 0;
	
	private boolean fadeOut = false;
	private boolean changeTrack = false;
	
	private float fadeOutValue = 1.0f;
	
	private float fadeSpeed = 0.001f;
	
	private boolean pause = false;
	private boolean stop = true;
	
	private boolean loopTrack = false;
	
	private float volume = 1.0f;

	private static Musicplayer musicplayer = null;

	private Musicplayer() {
	}

	public static Musicplayer getInstance() {
		if (musicplayer == null) {
			musicplayer = new Musicplayer();
		}

		return musicplayer;
	}
	
	public void addTrack(String track) {
		if(!tracks.containsKey(track)) {
			tracks.put(track, new Sound(track));
		}
		
		tracksID.add(track);
		
		if(current.equals("")) {
			current = track;
		}
	}
	
	public void removeTrack(String track) {
		tracks.remove(track);
		tracksID.remove(track);
	}
	
	public void previousTrack() {
		next = tracksID.indexOf(current) - 1;
		
		if(next > 0) {
			next = tracksID.size() - 1;
		}
		
		if(tracks.get(current).isPlaying()) {
			changeTrack = true;
			fadeOut = true;
			
			stop = true;
			pause = false;
		} else {
			tracks.get(current).stop();
			
			current = tracksID.get(next);
			calculateNext();
			
			tracks.get(current).setVolume(volume);
			tracks.get(current).play();
		}
	}
	
	public void play() {
		if(tracks.get(current).isPlaying()) {
			changeTrack = true;
			fadeOut = true;
		} else {
			tracks.get(current).play();
		}
		
		stop = false;
		pause = false;
	}
	
	public void pause() {
		fadeOut = true;
		pause = true;
		stop = false;
	}
	
	public void stop() {
		fadeOut = true;
		pause = false;
		stop = true;
	}
	
	public void nextTrack() {	
		next = tracksID.indexOf(current) + 1;
		
		if(next > tracksID.size() - 1) {
			next = 0;
		}
		
		if(tracks.get(current).isPlaying()) {
			changeTrack = true;
			fadeOut = true;
			
			stop = true;
			pause = false;
		} else {
			tracks.get(current).stop();
			
			current = tracksID.get(next);
			calculateNext();
			
			tracks.get(current).setVolume(volume);
			tracks.get(current).play();
		}
	}
	
	public void update(float timeElapsed) {
		if(tracks == null || tracks.get(current) == null) {
			//TODO fix this
			return;
		}
		
		tracks.get(current).setPosition(SoundManager.getListenerPosition());
		
		if(!tracks.get(current).isPlaying() && !pause && !stop) {
			current = tracksID.get(next);
			calculateNext();
			
			tracks.get(current).play();
		}
		
		if(fadeOut) {
			fadeOutValue -= fadeSpeed * timeElapsed;

			tracks.get(current).setVolume(fadeOutValue);
				
			if(fadeOutValue <= 0.0f) {
				fadeOutValue = volume;
				
				fadeOut = false;
				
				if(pause) {
					tracks.get(current).pause();
				} else {
					tracks.get(current).stop();
				}
				
				tracks.get(current).setVolume(fadeOutValue);
				
				if(changeTrack) {
					current = tracksID.get(next);
					calculateNext();
					
					changeTrack = false;
				
					tracks.get(current).play();
				}
			}
		}
	}
	
	private void calculateNext() {
		if(!loopTrack) {
			next = (int)(Math.random() * tracksID.size());
		}
	}
	
	public void setLoopTrack(boolean loop) {
		if(loop) {
			loopTrack = true;
			next = tracksID.indexOf(current);
		} else {
			loopTrack = false;
			calculateNext();
		}
	}
	
	public void setVolume(float volume) {
		this.volume = volume;
		
		if(!fadeOut) {
			fadeOutValue = volume;
			tracks.get(current).setVolume(volume);
		}
	}
}
